home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir40 / progref2.zip / CHAP9 < prev    next >
Text File  |  1988-09-29  |  37KB  |  759 lines

  1. CHAPTER 9
  2.  
  3.  Programming Technical Reference - IBM
  4.  Copyright 1988, Dave Williams
  5.  
  6.  
  7.                        INSTALLABLE DEVICE DRIVERS
  8.  
  9.  
  10. DEVICE DRIVER FORMAT
  11.  
  12.  A device driver is a COM or EXE file that contains all of the code needed to
  13. control an add-in device. It has a special header to identify it as a device,
  14. define the strategy and interrupt entry points, and define its various
  15. attributes.
  16.  
  17. NOTE: For device drivers the COM file must not use the ORG 100h. Since the
  18.       driver does not use the program segment prefix, it is simply loaded
  19.       without offset. Therefore the memory image file must have an origin of 0 
  20.       (ORG 0 or no ORG statement).
  21.  
  22.  
  23. TYPES OF DEVICES
  24.  
  25.  There are two types of devices: Character devices and Block devices. Their 
  26. attributes are as follows:
  27.  
  28.  Character devices are designed to do character I/O in a serial manner like 
  29. CON, AUX, and PRN. These devices have names like CON, AUX, CLOCK$, and you can 
  30. open channels (handles or FCBs) to do input and output with them. Because 
  31. character devices have only one name, they can only support one device.
  32.  
  33.  Block devices are the fixed disk or diskette drives on a system. They can do 
  34. random I/O in peices called blocks, which are usually the physical sector 
  35. size of the disk. These devices are not named as character devices are, and 
  36. cannot be opened directly. Instead they are mapped by using the drive letters 
  37. A,B,C etc. Block devices can have units within them. In this way, a single block
  38. driver can be responsible for one or more disk drives. For example, the first
  39. block device driver can be responsible for drives A,B,C,and D. This means it has
  40. four units defined and therefore takes up four drive letters. The position of
  41. the driver in the chain of all drives determines the way in which the drive
  42. letters correspond. For example, if the device driver is the first block driver
  43. in the device chain, and it defines four units, then these devices are called
  44. A,B,C, and D. If the second device driver defines three units, then those units
  45. are E,F,and G. DOS 1.x allows 16 devices. DOS 2.x allows 63, and DOS 3.x allows
  46. 26. It is recommended that drivers limit themselves to 26 devices for
  47. compatibility with DOS 3.x.
  48.  
  49.  DOS doesn't care about the position of installed character devices versus 
  50. block devices. The installed character devices get put into the chain ahead of
  51. resident character devices so that you can override the system's default driver
  52. for CON etc.
  53.  
  54.  Although it is sometimes beleived that installed block devices get linked into
  55. the chain BEHIND the resident block devices, if you look at the actual device
  56. chain, this is not true (though it is true in the sense that installed block
  57. devices get assigned drive letters in sequence, starting with the next letter
  58. after the last one assigned to a resident block device).
  59.  
  60.  
  61.  
  62. DEVICE HEADER
  63.  
  64.  A device driver requires a device header at the beginning of the file. This 
  65. is the format of the device header:
  66.  
  67.                 Field                           Length
  68.  
  69.         Pointer to next device header field     dword
  70.         Attribute                               word
  71.         Pointer to device strategy routine      word
  72.         Pointer to device interrupt routine     word
  73.         Name/Unit field                         8 bytes
  74.  
  75.  
  76. POINTER TO NEXT DEVICE HEADER FIELD
  77.  
  78.  The device header field is a pointer to the device header of the next device 
  79. driver. It is a doubleword field that is set by DOS at the time the device 
  80. driver is loaded. The first word is an offset and the second word is the 
  81. segment.
  82.  If you are loading only one device driver, set the device header field to -1 
  83. before loading the device. If you are loading more than one device driver, set 
  84. the first word of the device driver header to the offset of the next device 
  85. driver's header. Set the device driver header field of the last device driver 
  86. to -1.
  87.  
  88.  
  89. ATTRIBUTE FIELD
  90.  
  91.  The attribute field is a word field that describes the attributes of the 
  92. device driver to the system. The attributes are:
  93.  
  94.         word    bits (decimal)
  95.                 15      1       character device
  96.                         0       block device
  97.                 14      1       supports IOCTL
  98.                         0       doesn't support IOCTL
  99.                 13      1       non-IBM format (block only)
  100.                         0       IBM format
  101.                 12      not documented - unknown
  102.                 11      1       supports removeable media
  103.                         0       doesn't support removeable media
  104.                 10      reserved for DOS
  105.              through
  106.                 4       reserved for DOS
  107.                 3       1       current block device
  108.                         0       not current block device
  109.                 2       1       current NUL device
  110.                         0       not current NUL device
  111.                 1       1       current standard output device
  112.                         0       not current standard output device
  113.  
  114.  
  115.  
  116. BIT 15  is the device type bit. Use it to tell the system the that driver is a
  117.         block or character device.
  118.  
  119. BIT 14  is the IOCTL bit. It is used for both character and block devices. Use 
  120.         it to tell DOS whether the device driver can handle control strings
  121.         through the IOCTL function call 44h.
  122.          If a device driver cannot process control strings, it should set bit
  123.         14 to 0. This way DOS can return an error is an attempt is made through
  124.         the IOCTL function call to send or receive control strings to the
  125.         device. If a device can process control strings, it should set bit 14 
  126.         to 1. This way, DOS makes calls to the IOCTL input and output device 
  127.         function to send and receive IOCTL strings.
  128.          The IOCTL functions allow data to be sent to and from the device 
  129.         without actually doing a normal read or write. In this way, the device
  130.         driver can use the data for its own use, (for example, setting a baud
  131.         rate or stop bits, changing form lengths, etc.) It is up to the device
  132.         to interpret the information that is passed to it, but the information
  133.         must not be treated as a normal I/O request.
  134.  
  135.  
  136. BIT 13  is the non-IBM format bit. It is used for block devices only. It affects
  137.         the operation of the Get BPB (BIOS parameter block) device call.
  138.  
  139. BIT 11  is the open/close removeable media bit. Use it to tell DOS if the 
  140.         device driver can handle removeable media. (DOS 3.x only)
  141.  
  142. BIT 3   is the clock device bit. It is used for character devices only. Use it 
  143.         to tell DOS if your character device driver is the new CLOCK$ device.
  144.  
  145. BIT 2   is the NUL attribute bit. It is used for character devices only. Use it
  146.         to tell DOS if your character device driver is a NUL device. Although
  147.         there is a NUL device attribute bit, you cannot reassign the NUL device.
  148.         This is an attribute that exists for DOS so that DOS can tell if the NUL
  149.         device is being used.
  150.  
  151. BIT 0   are the standard input and output bits. They are used for character
  152.   &     devices only. Use these bits to tell DOS if your character device 
  153. BIT 1   driver is the new standard input device or standard output device.
  154.  
  155.  
  156. POINTER TO STRATEGY AND INTERRUPT ROUTINES
  157.  
  158.  These two fields are pointers to the entry points of the strategy and input 
  159. routines. They are word values, so they must be in the same segment as the 
  160. device header.
  161.  
  162.  
  163. NAME/UNIT FIELD
  164.  
  165.  This is an 8-byte field that contains the name of a character device or the 
  166. unit of a block device. For the character names, the name is left-justified and
  167. the space is filled to 8 bytes. For block devices, the number of units can be 
  168. placed in the first byte. This is optional because DOS fills in this location 
  169. with the value returned by the driver's INIT code.
  170.  
  171.  
  172. CREATING A DEVICE DRIVER
  173.  
  174.  To create a device driver that DOS can install, perform the following:
  175.  
  176. 1) Create a memory image file or an EXE file with a device header at the start 
  177.    of the file.
  178. 2) Originate the code (including the device header) at 0, not 100h.
  179. 3) Set the next device header field. Refer to "Pointer to Next Device Header 
  180.    Attribute Field" for more information.
  181. 4) Set the attribute field of the device header. Refer to "Attribute Field" for 
  182.    more information.
  183. 5) Set the entry points for the interrupt and strategy routines.
  184. 6) Fill in the name/unit field with the name of the character device or the unit
  185.    number of the block device.
  186.  
  187.  DOS always processes installable character device drivers before handling the 
  188. default devices. So to install a new CON device, simply name the device CON. 
  189. Be sure to set the standard input device and standard output device bits in 
  190. the attribute field of a new CON device. The scan of the device list stops on 
  191. the first match so the installable device driver takes precedence.
  192.  
  193. NOTE: Because DOS can install the device driver anywhere in memory, care 
  194.       must be taken in any FAR memory references. You should not expect that 
  195.       your driver will be loaded in the same place every time.
  196.  
  197.  
  198.  
  199. INSTALLING DEVICE DRIVERS
  200.  
  201.  DOS installs new device drivers dynamically at boot time by reading and 
  202. processing the DEVICE command in the config.sys file. For example, if you have 
  203. written a device driver called DRIVER1, to install it put this command in the 
  204. CONFIG.SYS file:
  205.                              DEVICE=DRIVER1
  206.  
  207.  DOS calls a device driver at its strategy entry point first, passing in a 
  208. request header the information describing what DOS wants the device driver 
  209. to do.
  210.  This strategy routine does not perform the request but rather queues the 
  211. request or saves a pointer to the request header. The second entry point is 
  212. the interrupt routine and is called by DOS immediately after the strategy 
  213. routine returns. The interrupt routine is called with no parameters. Its 
  214. function is to perform the operation based on the queued request and set up 
  215. any return infromation.
  216.  DOS passes the pointer to the request header in ES:BX. This structure consists
  217. of a fixed length header (Request Header) followed by data pertinent to the 
  218. operation to be performed.
  219.  
  220. NOTE: It is the responsibility of the device driver to preserve the machine 
  221.       state. For example, save all registers on entry and restore them on exit.
  222.  
  223.  The stack used by DOS has enough room on it to save all the registers. If more
  224. stack space is needed, it is the device driver's responsibility to allocate and
  225. maintain another stack.
  226.  All calls to execute device drivers are FAR calls. FAR returns should be 
  227. executed to return to DOS.
  228.  
  229.  
  230.  
  231. INSTALLING CHARACTER DEVICES
  232.  
  233.  One of the functions defined for each device is INIT. This routine is called 
  234. only once when the device is installed and never again. The INIT routine returns
  235. the following:
  236.  
  237. A) A location to the first free byte of memory after the device driver, like a
  238.    TSR that is stored in the terminating address field. This way, the 
  239.    initialization code can be used once and then thrown away to save space.
  240. B) After setting the address field, a character device driver can set the status
  241.    word and return.
  242.  
  243.  
  244. INSTALLING BLOCK DEVICES
  245.  
  246.  Block devices are installed in the same way as character devices. The 
  247. difference is that block devices return additional information. Block devices 
  248. must also return:
  249.  
  250. A) The number of units in the block device. This number determines the logical 
  251.    names the devices will have. For example, if the current logical device 
  252.    letter is F at the time of the install call, and the block device driver INIT
  253.    routine returns three logical units, the letters G, H, and I are assigned to 
  254.    the units. The mapping is determined by the position of the driver in the 
  255.    device list and the number of units in the device. The number of units 
  256.    returned by INIT overrides the value in the name/unit field of the device 
  257.    header.
  258. B) A pointer to a BPB (BIOS parameter block) pointer array. This is a pointer 
  259.    to an array of *n* word pointers there *n* is the number of units defined. 
  260.    These word pointers point to BPBs. This way, if all of the units are the 
  261.    same, the entire array can point to the same BPB to save space.
  262.     The BPB contains information pertinent to the devices such as the sector 
  263.    size, number of sectors per allocation unit, and so forth. The sector size of
  264.    the BPB cannot be greater than the maximum allotted size set at DOS 
  265.    initialization time.
  266.    NOTE: This array must be protected below the free pointer set by the return.
  267. C) The media descriptor byte. This byte is passed to devices so that they know 
  268.    what parameters DOS is currently using for a particular drive unit.
  269.  
  270.  Block devices can take several approaches. They can be *dumb* or *smart*. A 
  271. dumb device would define a unit (and therefore a BPB) for each possible media 
  272. drive combination. Unit 0=drive 0;single side, unit 1=drive 0;double side, etc.
  273.  For this approach, the media descriptor bytes would mean nothing. A smart 
  274. device would allow multiple media per unit. In this case, the BPB table 
  275. returned at INIT must define space large enough to acommodate the largest 
  276. possible medias supported (sector size in BPB must be as large as maximum 
  277. sector size DOS is currently using). Smart drivers will use the media byte to 
  278. pass information about what media is currently in a unit.
  279.  
  280.  
  281. REQUEST HEADER
  282.  
  283.  The request header passes the information describing what DOS wants the 
  284. device driver to do.
  285.  
  286. ┌──────────┬───────────────────────────────────────────────────────────────────┐
  287. │  Length  │                       F i e l d                                   │
  288. ├──────────┼───────────────────────────────────────────────────────────────────┤
  289. │   BYTE   │ Length in bytes of the request header plus any data at end        │
  290. ├──────────┼───────────────────────────────────────────────────────────────────┤
  291. │   BYTE   │ Unit code. The subunit the operation is for (minor device)        │
  292. │          │ Has no meaning for character devices.                             │
  293. ├──────────┼───────────────────────────────────────────────────────────────────┤
  294. │   WORD   │ Command code                                                      │
  295. ├──────────┼───────────────────────────────────────────────────────────────────┤
  296. │ 8 BYTES  │ Deserved for DOS                                                  │
  297. ├──────────┼───────────────────────────────────────────────────────────────────┤
  298. │(variable)│ Data appropriate for the operation                                │
  299. └──────────┴───────────────────────────────────────────────────────────────────┘
  300.  
  301.  
  302. UNIT CODE FIELD
  303.  
  304.  The unit code field identifies which unit in a block device driver the request
  305. is for. For example, if a block device driver has three units defined, then the
  306. possible values of the unit code field would be 0,1,and 2.
  307.  
  308.  
  309. COMMAND CODE FIELD
  310.  
  311.  The command code field in the request header can have the following values:
  312.  
  313.       CODE         FUNCTION
  314.  
  315.         0       INIT
  316.         1       MEDIA CHECK      (block only,NOP for character)
  317.         2       BUILD BPB        (block only, NOP for character)
  318.         3       IOCTL input      (called only if IOCTL bit is 1)
  319.         4       INPUT            (read)
  320.         5       NONDESTRUCTIVE INPUT NO WAIT (character devices only)
  321.         6       INPUT STATUS     (character devices only)
  322.         7       INPUT FLUSH      (character devices only)
  323.         8       OUTPUT           (write)
  324.         9       OUTPUT           (write with verify)
  325.         10      OUTPUT STATUS    (character devices only)
  326.         11      OUTPUT FLUSH     (character devices only)
  327.         12      IOCTL OUTPUT     (called only if IOCTL bit is 1)
  328.         13      DEVICE OPEN      (called only if OPEN/CLOSE/RM bit is set)
  329.         14      DEVICE CLOSE     (called only if OPEN/CLOSE/RM bit is set)
  330.         15      REMOVEABLE MEDIA (called only if OPEN/CLOSE/RM bit is set and
  331.                                   device is block)
  332.  
  333. NOTE: Command codes 13,14,and 15 are for use with DOS versions 3.x.
  334.  
  335.  
  336. STATUS FIELD
  337. The status field in the request header contains:
  338.  
  339. ┌──────────────────────────────────────────────────────────────────────────────┐
  340. │            D E V I C E    D R I V E R    S T A T U S    F I E L D            │
  341. ├───────┬───┬──────────────────────────────────────────────────────────────────┤
  342. │   B   │ 0 │                                                                  │
  343. │       │ 1 │                                                                  │
  344. │   Y   │ 2 │                                                                  │
  345. │       │ 3 │   Error message return code                                      │
  346. │   T   │ 4 │   (with bit 15=1)                                                │
  347. │       │ 5 │                                                                  │
  348. │   E   │ 6 │                                                                  │
  349. │       │ 7 │                                                                  │
  350. ├───────┼───┼──────────────────────────────────────────────────────────────────┤
  351. │  bit  │ 8 │   DONE                                                           │
  352. ├───────┼───┼──────────────────────────────────────────────────────────────────┤
  353. │  bit  │ 9 │   BUSY                                                           │
  354. ├───────┼───┴─────┬────────────────────────────────────────────────────────────┤
  355. │  bits │ 10 - 14 │   Reserved                                                 │
  356. ├───────┼────┬────┴────────────────────────────────────────────────────────────┤
  357. │  bit  │ 15 │   Error                                                         │
  358. └───────┴────┴─────────────────────────────────────────────────────────────────┘
  359.  
  360.  The status word field is zero on entry and is set by the driver interrupt 
  361. routine on return.
  362.  
  363. BIT 15  is the error bit. If this bit is set, the low 8 bits of the status word
  364.         (7-0) indicate the error code.
  365.  
  366. BITS 14-10 are reserved.
  367.  
  368. BIT 9   is the busy bit. It is only set by status calls and the removable media 
  369.         call. See "STATUS" and "REMOVABLE MEDIA" in this chapter for more 
  370.         information about the calls.
  371.  
  372. BIT 8   is the done bit. If it is set, it means the operation is complete. The 
  373.         driver sets the bit to 1 when it exits.
  374.  
  375.  The low 8 bits of the status word define an error message if bit 15 is set. 
  376. These errors are:
  377.  
  378.         00h  Write protect violation   01h  Unknown unit
  379.         02h  Device not ready          03h  Unknown command
  380.         04h  CRC error                 05h  Bad drive request structure length
  381.         06h  seek error                07h  unknown media
  382.         08h  sector not found          09h  printer out of paper
  383.         0Ah  write fault               0Bh  read fault
  384.         0Ch  general failure           0Dh  reserved
  385.         0Eh  reserved                  0Fh  invalid disk change
  386.  
  387.  
  388. DEVICE DRIVER FUNCTIONS
  389.  
  390.  All strategy routines are called with ES:BX pointing to the request header. 
  391. The interrupt routines get the pointers to the request header from the queue 
  392. the strategy routines store them in. The command code in the request header 
  393. tells the driver which function to perform.
  394. NOTE: all DWORD pointers are stored offset first, then segment.
  395.  
  396. The following function call parameters are described:
  397.  
  398.         INIT
  399.         MEDIA CHECK
  400.         BUILD BPB (BIOS PARAMETER BLOCK)
  401.         MEDIA DESCRIPTOR BYTE
  402.         INPUT OR OUTPUT
  403.         NONDESTRUCTIVE INPUT NO WAIT
  404.         STATUS
  405.         FLUSH
  406.         OPEN OR CLOSE
  407.         REMOVABLE MEDIA
  408.  
  409.  
  410. INIT
  411. Command code=0
  412.         ES:BX   pointer to request header. Format of header:
  413.                 length           field
  414.                 13 bytes  request header
  415.                  dword    number of units (not set by character devices)
  416.                  dword    Ending address of resident program code
  417.                  dword    Pointer to BPB array (not set by character devices)
  418.                           /pointer to remainder of arguments
  419.                   byte    Drive number (3x only)
  420.  
  421. The driver must do the following:
  422.  
  423.         A) set the number of units (block devices only)
  424.         B) set up the pointer to the BPB array (block devices only)
  425.         C) perform any initialization code (to modems, printers, etc)
  426.         D) Set the ending address of the resident program code
  427.         E) set the status word in the request header.
  428.  
  429.  To obtain information obtained from CONFIG.SYS to a device driver at INIT 
  430. time, the BPB pointer field points to a buffer containing the information 
  431. passed from CONFIG.SYS following the =. The buffer that DOS passes to the 
  432. driver at INIT after the file specification contains an ASCII string for the 
  433. file OPEN. The ASCII string (ending in 0h) is terminated by a carriage return 
  434. (0Dh) and linefeed (0Ah). If there is no parameter information after the file 
  435. specification, the file specification is immediately followed by a linefeed 
  436. (0Ah). This information is read-only and only system calls 01h-0Ch and 30h can 
  437. be issued by the INIT code of the driver.
  438.  The last byte parameter contains the drive letter for the first unit of a 
  439. block driver. For example, 0=A, 1=B etc.
  440.  If an INIT routine determines that it cannot set up the device and wants to 
  441. abort without using any memory, follow this procedure:
  442.  
  443.         A) set the number of units to 0
  444.         B) set the ending offset address at 0
  445.         C) set the ending offsret segment address to the code segment (CS)
  446.  
  447. NOTE: If there are multiple device drivers in a single memory image file, the 
  448.       ending address returned by the last INIT called is the one DOS uses. It is
  449.       recommended that all device drivers in a single memory image file return
  450.       the same ending address.
  451.  
  452.  
  453. MEDIA CHECK
  454. command code=1
  455.         ES:BX   pointer to request header. Format of header:
  456.                 length          field
  457.                 13 bytes  request header
  458.                 byte      media descriptor from DOS
  459.                 byte      return
  460.                 dword     returns a pointer to the previous volume ID (if bit
  461.                           11=1 and disk change is returned) (DOS 3.x)
  462.  
  463.  When the command code field is 1, DOS calls MEDIA CHECK for a drive unit and 
  464. passes its current media descriptor byte. See "Media Descriptor Byte" later in 
  465. this chapter for more information about the byte. MEDIA CHECK returns one of 
  466. the following:
  467.  
  468.         A) media not changed             C) not sure
  469.         B) media changed                 D) error code
  470.  
  471. The driver must perform the following:
  472.         A) set the status word in the request header
  473.         B) set the return byte
  474.                -1       media has been changed
  475.                 0       don't know if media has been changed
  476.                 1       media has not been changed
  477.  
  478.  DOS 3.x: If the driver has set the removable media bit 11 of the device header
  479. attribute word to 1 and the driver returns -1 (media changed), the driver must 
  480. set the DWORD pointer to the previous volume identification field. If DOS 
  481. determines that the media changed is an error, DOS generates an error 0Fh 
  482. (invalid disk change) on behalf of the device. If the driver does not implement
  483. volume identification support, but has bit 11 set to 1, the driver should set a
  484. pointer to the string "NO NAME",0.
  485.  
  486.  
  487. MEDIA DESCRIPTOR
  488.  Currently the media descriptor byte has been defined for a few media types. 
  489. This byte should be idetnical to the media byte if the device has the non-IBM 
  490. format bit off. These predetermined values are:
  491.  
  492. media descriptor byte =>    1  1  1  1  1  0  0  0
  493.  (numerical order)          7  6  5  4  3  2  1  0
  494.  
  495.        BIT                MEANING        
  496.  
  497.         0       1=2 sided       0=not 2 sided
  498.         1       1=8 sector      0=not 8 sector
  499.         2       1=removeable    0=nonremoveable
  500.        3-7      must be set to 1
  501.  
  502.  
  503. Examples of current DOS media descriptor bytes:
  504.  
  505.            media      sides   sectors  ID byte
  506.  
  507.         hard disk       *       *       0F8h
  508.         5-1/4 floppy    2       15      0F9h
  509.         5-1/4 floppy    1       9       0FCh
  510.         5-1/4 floppy    2       9       0FDh
  511.         5-1/4 floppy    2       8       0FFh
  512.         5-1/4 floppy    1       8       0FEh
  513.         8" floppy       1       26      0FEh *
  514.         8" floppy       2       26      0FDh
  515.         8" floppy       2       8       0FEh *
  516.  
  517. *NOTE: The two Media Descriptor Bytes that are the same for 8" diskettes (0FEh) 
  518. are not a misprint. To determine whether you are using a single sided or double
  519. sided diskette, attempt to read the second side, and if an error occurs you can
  520. assume the diskette is single sided.
  521.  
  522.  
  523. BUILD BPB (BIOS Parameter Block)
  524. command code =2
  525.         ES:BX   pointer to request header. Format:
  526.                 length          field
  527.                 13 bytes  request header
  528.                 byte      media descriptor from DOS
  529.                 dword     transfer address (buffer address)
  530.                 dword     pointer to BPB table
  531.  
  532. DOS calls BUILD BPB under the following two conditions:
  533.  
  534. A) If "media changed" is returned
  535. B) If "not sure" is returned, there are no used buffers. Used buffers are 
  536.    buffers with changed data that has not yet been written to the disk.
  537.  
  538. The driver must do the following:
  539.  
  540. A) set the pointer to the BPB
  541. B) set the status word in the request header.
  542.  
  543.  The driver must determine the correct media type currently in the unit to 
  544. return the pointer to the BPB table. The way the buffer is used (pointer 
  545. passed by DOS) is determined by the non-IBM format bit in the attribute field 
  546. of the device header. If bit 13=0 (device is IBM compatible), the buffer 
  547. contains the first sector of the FAT (most importantly the FAT ID byte). The 
  548. driver must not alter this buffer in this case. If bit 13=1 the buffer is a 
  549. one sector scratch area which can be used for anything.
  550.  For drivers that support volume identification and disk change, the call 
  551. should cause a new volume identification to be read off the disk. This call 
  552. indicates that the disk has been legally changed.
  553.  If the device is IBM compatible, it must be true that the first sector of the 
  554. first FAT is located at the same sector for all possible media. This is 
  555. because the FAT sector is read before the media is actually determined.
  556.  The information relating to the BPB for a particular media is kept in the boot
  557. sector for the media. In particular, the format of the boot sector is:
  558.  
  559. ┌──────────────────────────────────────────────────────────────────────────────┐
  560. │ For DOS 2.x, 3 byte near jump (0E9h) For DOS 3.x, 2 byte near jump (0EBh)    │
  561. │ followed by a NOP (90h)                                                      │
  562. ├──────────┬───────────────────────────────────────────────────────────────────┤
  563. │ 8 bytes  │  OEM name and version                                             │
  564. ├──────────┼─────┬─────────────────────────────────────────────────────────────┤
  565. │   BYTE   │     │  sectors per allocation unit (must be a power of 2)         │
  566. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  567. │   WORD   │  B  │  reserved sectors (strarting at logical sector 0)           │
  568. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  569. │   BYTE   │     │  number of FATs                                             │
  570. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  571. │   WORD   │  P  │  max number of root directory entries                       │
  572. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  573. │   WORD   │     │  number of sectors in logical image (total number of        │
  574. │          │     │  sectors in media, including boot sector directories, etc.) │
  575. ├──────────┤  B  ├─────────────────────────────────────────────────────────────┤
  576. │   BYTE   │     │  media descriptor                                           │
  577. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  578. │   WORD   │     │  number of sectors occupied by a single FAT                 │
  579. ├──────────┼─────┴─────────────────────────────────────────────────────────────┤
  580. │   WORD   │  sectors per track                                                │
  581. ├──────────┼───────────────────────────────────────────────────────────────────┤
  582. │   WORD   │  number of heads                                                  │
  583. ├──────────┼───────────────────────────────────────────────────────────────────┤
  584. │   WORD   │  number of hidden sectors                                         │
  585. └──────────┴───────────────────────────────────────────────────────────────────┘
  586.  
  587.  The three words at the end return information about the media. The number of
  588. heads is useful for supporting different multihead drives that have the same
  589. storage capacity but a different number of surfaces. The number of hidden
  590. sectors is useful for drive partitioning schemes.
  591.  
  592.  
  593. INPUT / OUTPUT
  594. command codes=3,4,8,9,and 12
  595.         ES:BX   pointer to request header. Format:
  596.                 length          field
  597.                 13 bytes  request header
  598.                 byte      media descriptor byte
  599.                 dword     transfer address (buffer address)
  600.                 word      byte/sector count
  601.                 dword     (DOS 3.x) pointer to the volume ID if error code 0Fh
  602.                           is returned
  603.  
  604. The driver must perform the following:
  605.         A) set the status word in the request header
  606.         B) perform the requested function
  607.         C) set the actual number of sectors or bytes tranferred
  608.  
  609. NOTE: No error checking is performed on an IOCTL I/O call. However the driver 
  610.       must set the return sector or byte count to the actual number of bytes 
  611.       transferred.
  612.  
  613.  
  614. The following applies to block device drivers: 
  615.  
  616.  Under certain circumstances the device driver may be asked to do a write 
  617. operation of 64k bytes that seems to be a *wrap around* of the transfer address
  618. in the device driver request packet. This arises due to an optimization added to
  619. write code in DOS. It will only happen in writes that are within a sector size
  620. of 64k on files that are being exetended past the current end of file. It is 
  621. allowable for the device driver to ignore the balance of the write that wraps 
  622. around, if it so chooses. For example, a write of 10000h bytes worth of sectors
  623. with a transfer address of XXXX:1 ignores the last two bytes.
  624.  
  625. Remember: A program that uses DOS function calls can never request an input or 
  626.           output function of more than 0FFFFh bytes, therefore, a wrap around 
  627.           in the transfer (buffer) segment can never occur. It is for this 
  628.           reason you can ignore bytes that would have wrapped around in the 
  629.           tranfer segment.
  630.  
  631.  If the driver returns an error code of 0Fh (invalid disk change) it must put 
  632. a DWORD pointer to an ASCIIZ string which is the correct volume ID to ask the 
  633. user to reinsert the disk.
  634.  
  635. DOS 3.x:
  636.  The reference count of open files on the field (maintained by the OPEN and 
  637. CLOSE calls) allows the driver to determine when to return error 0Fh. If there 
  638. are no open files (reference count=0) and the disk has been changed, the I/O 
  639. is all right, and error 0Fh is not returned. If there are open files 
  640. (reference count > 0) and the disk has been changed, an error 0Fh condition 
  641. may exist.
  642.  
  643.  
  644. NONDESTRUCTIVE INPUT NO WAIT
  645. command code=5
  646.         ES:BX   pointer to request header. Format:
  647.                 length          field
  648.                 13 bytes  request header
  649.                 byte      read from device
  650.  
  651. The driver must do the following:
  652.         A) return a byte from the device
  653.         B) set the status word in the request header.
  654.  
  655.  If the character device returns busy bit=0 (characters in the buffer), then 
  656. the next character that would be read is returned. This character is not removed
  657. form the buffer (hence the term nondestructive input). This call allows DOS to
  658. look ahead one character.
  659.  
  660.  
  661. STATUS
  662. command codes=8 and 10
  663.         ES:BX   pointer to a request header. Format:
  664.                 length          field
  665.                 13 bytes  request header
  666.  
  667. This driver must perform the following:
  668.         A) perform the requested function
  669.         B) set the busy bit
  670.         C) set the status word in the request header.
  671.  
  672. The busy bit is set as follows:
  673.  
  674.  For input on character devices: if the busy bit is 1 on return, a write 
  675. request would wait for completion of a current request. If the busy bit is 0, 
  676. there is no current request. Therefore, a write request would start immediately.
  677.  
  678.  For input on character devices with a buffer: if the busy bit is 1 on return, 
  679. a read request does to the physical device. If the busy bit is 0, there are 
  680. characters in the device buffer and a read returns quickly. It also indicates 
  681. that a user has typed something. DOS assumes all character devices have a type-
  682. ahead input buffer. Devices that do not have this buffer should always return 
  683. busy=0 so that DOS does not hang waiting for information to be put in a buffer
  684. that does not exist.
  685.  
  686.  
  687. FLUSH
  688. command codes=7 and 11
  689.         ES:BX   pointer
  690.                 length          field
  691.                 13 bytes  request header
  692.  
  693.  This call tells the driver to flush (terminate) all pending requests that it 
  694. has knowledge of. Its primary use is to flush the input queue on character 
  695. devices.
  696.  The driver must set the status word in the request header upon return.
  697.  
  698.  
  699. OPEN or CLOSE (3.x)
  700. command codes=13 and 14
  701.         ES:BX   pointer
  702.                 length          field
  703.                 13 bytes  static request header
  704.  
  705.  These calls are designed to give the device information about the current file
  706. activity on the device if bit 11 of the attribute word is set. On block 
  707. devices, these calls can be used to manage local buffering. The device can keep
  708. a reference count. Every OPEN causes the device to increment the reference
  709. count. Every CLOSE causes the device to decrement the reference count. When the
  710. reference count is 0, if means there are no open files in the device. Therefore,
  711. the device should flush buffers inside the device it has written to because now
  712. the user can change the media on a removeable media drive. If the media had been
  713. changed, it is advisable to reset the reference count to 0 without flushing the
  714. buffers. This can be thought of as "last close causes flush". These calls are 
  715. more useful on character devices. The OPEN call can be used to send a device 
  716. initialization string. On a printer, this could cause a string to be sent to set
  717. the font, page size, etc. so that the printer would always be in a known state
  718. in the I/O stream. Similarly, a CLOSE call can be used to send a post string 
  719. (like a form feed) at the end of an I/O stream. Using IOCTL to set these pre and
  720. post strings provides a flexible mechanism of serial I/O device stream control.
  721.  
  722. NOTE: Since all processes have access to STDIN,STDOUT,STDERR,STDAUX, and STDPRN
  723.       (handles 0,1,2,3,and 4) the CON, AUX, and PRN devices are always open.
  724.  
  725.  
  726. REMOVABLE MEDIA (DOS 3.x)
  727. command code=15
  728.         ES:BX   pointer
  729.                 length          field
  730.                 13 bytes  status request header
  731.  
  732.  To use this call, set bit 11 of the attribute field to 1. Block devices can 
  733. only use this call through a subfunction of the IOCTL function call (44h). 
  734. This call is useful because it allows a utility to know whether it is dealing 
  735. with a nonremovable media drive or with a removable media drive. For example, 
  736. the FORMAT utility needs to know whether a drive is removable or nonremovable 
  737. because it prints different versions of some prompts.
  738.  
  739.  The information is returned in the BUSY bit of the status word. If the busy 
  740. bit is 1, the media is nonremovable. 
  741.  
  742. NOTE: No error checking is performed. It is assumed that this call always 
  743.       succeeds.
  744.  
  745.  
  746. THE CLOCK$ DEVICE
  747.  
  748.  To allow a clock board to be integrated into the system for TIME and DATE,
  749. the CLOCK$ device is used. This device defines and performs functions like any
  750. other character device (most functions will be reset done bit, reset error bit,
  751. and return). When a read or write to this device occurs, 6 bytes are
  752. transferred. The first 2 bytes are a word, which is the count of days since
  753. 01-01-80. The third byte is minutes, the fourth is hours, the fifth is
  754. hundredths of a second, and the sixth is seconds. 
  755. Reading the CLOCK$ device gets the date and time, writing to it sets the date 
  756. and time.
  757.  
  758.  
  759.